﻿using FreeSql;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Syspetro.Core;
using Syspetro.Core.DbAccessor;
using Syspetro.Core.Encrypt;
using System;

namespace Syspetro.DepFreeSql
{
    public static class ServiceCollection
    {
        public static IHostBuilder AddFreeSql<T>(this IHostBuilder hostBuilder, string connectionString = null, params Type[] entityTypes) where T : BaseFreeSqlContext
        {
            InternalApp.ServiceCollection.AddFreeSql<T>(connectionString, entityTypes);
            return hostBuilder;
        }
        public static IServiceCollection AddFreeSql<T>(this IServiceCollection services, string connectionString = null, params Type[] entityTypes) where T : BaseFreeSqlContext
        {
            if (string.IsNullOrEmpty(connectionString))
            {
                connectionString = InternalApp.Configuration.GetSection("ConnectionString").Value;
            }
            var freestr = RSAHelper.Decrypt(connectionString);
            IFreeSql fsql;
#if DEBUG
            fsql = new FreeSql.FreeSqlBuilder()
                 .UseConnectionString(FreeSql.DataType.SqlServer, freestr)
                 .UseAutoSyncStructure(true)
                 .Build();
            fsql.CodeFirst.IsAutoSyncStructure = true;
            fsql.CodeFirst.SyncStructure(entityTypes);
#else
            fsql = new FreeSql.FreeSqlBuilder()
                 .UseConnectionString(FreeSql.DataType.SqlServer, freestr)
                 .UseAutoSyncStructure(false)
                 .Build();
            fsql.CodeFirst.IsAutoSyncStructure = false;
#endif
            fsql.Aop.CurdAfter += (s, e) =>
            {
                if (e.ElapsedMilliseconds > 400)
                {
                    Serilog.Log.Warning("数据库操作耗时:" + e.ElapsedMilliseconds, " Sql:" + e.Sql);
                }
            };
            services.AddFreeRepository(filter =>
                filter.Apply<EntitySoftDel<int>>("SoftDeleteInt", a => a.IsDeleted == false)
                .Apply<EntitySoftDel<Guid>>("SoftDeleteGuid", a => a.IsDeleted == false)
            );

            services.AddSingleton(fsql);
            services.AddFreeDbContext<T>(options => options.UseFreeSql(fsql));
            services.AddScoped<IDbContext, T>();
            return services;
        }
    }
}
